package pe.edu.upc.dsd.jjjar.upcbank.client.mvc;

import java.util.List;
import java.util.Map;

import pe.edu.upc.dsd.jjjar.upcbank.resources.client.Resources;
import pe.edu.upc.dsd.jjjar.upcbank.resources.client.config.ConfigBean;

import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.Style.SortDir;
import com.extjs.gxt.ui.client.data.BaseModel;
import com.extjs.gxt.ui.client.data.BasePagingLoadConfig;
import com.extjs.gxt.ui.client.data.BasePagingLoader;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.data.PagingLoadConfig;
import com.extjs.gxt.ui.client.data.PagingLoadResult;
import com.extjs.gxt.ui.client.data.PagingLoader;
import com.extjs.gxt.ui.client.data.RpcProxy;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.GridEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.toolbar.PagingToolBar;
import com.extjs.gxt.ui.client.widget.toolbar.SeparatorToolItem;
import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.rpc.AsyncCallback;

public abstract class SearchGrid<T extends BaseModel> extends LayoutContainer {

	private List<ColumnConfig> configs;
	private Grid<T> grid;
	private PagingLoader<PagingLoadResult<ModelData>> loader;
	
	public SearchGrid() {
		this.configs = createColumnConfig();
	}

	@Override
	protected void onRender(Element parent, int index) {
		super.onRender(parent, index);

		setLayout(new FitLayout());
		setBorders(false);
		
		createGrid();

		configGrid(grid);

	}

	public abstract void loadData(Object loadConfig, AsyncCallback<PagingLoadResult<T>> callback);
	public abstract List<ColumnConfig> createColumnConfig();
	public abstract void configGrid(Grid<T> grid);
	public abstract ToolBar createToolbar();

	private void createGrid() {

		// paging
		RpcProxy<PagingLoadResult<T>> proxy = new RpcProxy<PagingLoadResult<T>>() {
			@Override
			public void load(Object loadConfig,
					AsyncCallback<PagingLoadResult<T>> callback) {
				
				loadData(loadConfig, callback);
			}

		};
		
		
		loader = new BasePagingLoader<PagingLoadResult<ModelData>>(proxy);
		loader.setRemoteSort(true);
		ListStore<T> store = new ListStore<T>(loader);
		PagingToolBar ptoolBar = new PagingToolBar(ConfigBean.rowsByPage);
		ptoolBar.bind(loader);
				
		ColumnModel cm = new ColumnModel(configs);

		// Grid
		grid = new Grid<T>(store, cm);
		grid.getView().setForceFit(true);
		grid.setStateId("pagingSearch");  
		grid.setStateful(true);
		//grid.setSelectionModel(sm);
		grid.setColumnReordering(true);
		//grid.addPlugin(sm);
		grid.addListener(Events.Attach, new Listener<GridEvent<T>>() {
			public void handleEvent(GridEvent<T> be) {
				PagingLoadConfig config = new BasePagingLoadConfig();
				config.setOffset(0);
				config.setLimit(ConfigBean.rowsByPage);

				Map<String, Object> state = grid.getState();
				if (state.containsKey("offset")) {
					int offset = (Integer) state.get("offset");
					int limit = (Integer) state.get("limit");
					config.setOffset(offset);
					config.setLimit(limit);
				}
				if (state.containsKey("sortField")) {
					config.setSortField((String) state.get("sortField"));
					config.setSortDir(SortDir.valueOf((String) state
							.get("sortDir")));
				}
				//loader.load(config);
			}
		});
		grid.setLoadMask(true);
		grid.setBorders(false);
		
		// Panel
		ContentPanel cp = new ContentPanel();
		cp.setBorders(false);
		cp.setBodyBorder(false);
		cp.setHeaderVisible(false);
		cp.setIcon(Resources.ICONS.table());
		cp.setButtonAlign(HorizontalAlignment.CENTER);
		cp.setLayout(new FitLayout());
		cp.setBottomComponent(ptoolBar);
		cp.setSize(600, 300);

		/** Toolbar **/
		ToolBar toolBar = createToolbar();
		if (toolBar != null){
			toolBar.add(new SeparatorToolItem());
		}else
			toolBar = new ToolBar();
		
		  
	    toolBar.add(new Button("Refrescar", Resources.ICONS.plugin(), new SelectionListener<ButtonEvent>() {
			
			@Override
			public void componentSelected(ButtonEvent ce) {
				loader.load();
			}
		}));

		cp.setTopComponent(toolBar);
		
		grid.getAriaSupport().setLabelledBy(cp.getHeader().getId() + "-label");

		cp.add(grid);
		add(cp);
	}

	public void refresh(){
		loader.load();
	}
	
	public Grid<T> getGrid() {
		return grid;
	}
}
